<template>
	<div class="map_box">
		<div class="radar-container">
			<canvas
				id="radarCanvas"
				width="800"
				height="800"></canvas>
		</div>
	</div>
</template>

<script setup>
	import { onMounted, onUnmounted, reactive } from "vue";

	let canvas = null;
	let ctx = null;
	let width = null;
	let height = null;
	let centerX = null;
	let centerY = null;
	let radius = null;
	let scanSpeed = 0.005; // 扫描速度
	const center = { lat: 39.916, lng: 116.397 }; // 北京故宫
	const EARTH_RADIUS = 6371; // 地球半径（公里）
	const points = reactive([
		{
			lat: 40.6042,
			lng: 116.4074,
			color: "blue",
			bearing: 0,
			pulse: { active: false, progress: 0 },
		},
		{
			lat: 39.9042,
			lng: 117.4074,
			color: "green",
			bearing: 0,
			pulse: { active: false, progress: 0 },
		},
		{
			lat: 39.2042,
			lng: 116.4074,
			color: "orange",
			bearing: 0,
			pulse: { active: false, progress: 0 },
		},
		{
			lat: 39.9042,
			lng: 115.4074,
			color: "red",
			bearing: 0,
			pulse: { active: false, progress: 0 },
		},
		{
			lat: 40.9042,
			lng: 117.4074,
			color: "white",
			bearing: 0,
			pulse: { active: false, progress: 0 },
		},
	]);
	// 添加雷达扫描相关变量
	let scanSectorAngle = 0; // 扇形当前角度
	let scanSectorRange = Math.PI / 6; // 扇形扫描范围(30度)
	let scanGradient = null; // 扇形渐变
	let animationId = null; // 添加动画ID变量
	const PULSE_SPEED = 0.02; // 添加脉冲速度常量
	const PULSE_MAX_RADIUS = 20; // 脉冲最大半径

	onMounted(() => {
		canvas = document.getElementById("radarCanvas");
		ctx = canvas.getContext("2d");
		width = canvas.width;
		height = canvas.height;
		centerX = width / 2;
		centerY = height / 2;
		radius = Math.min(centerX, centerY);

		// 初始化扇形渐变
		initScanGradient();
		// 预计算所有点的方位角
		points.forEach(point => {
			point.bearing = getBearing(center.lat, center.lng, point.lat, point.lng);
		});
		// 启动雷达扫描动画并保存ID
		animationId = requestAnimationFrame(animateScan);
	});

	// 添加组件卸载时的清理钩子
	onUnmounted(() => {
		if (animationId) {
			cancelAnimationFrame(animationId);
			animationId = null;
		}
	});

	// 添加角度范围检测函数
	const isAngleInSector = (pointAngle, sectorAngle, sectorRange) => {
		// 将角度标准化到0-360度
		const normalizedPoint = ((pointAngle % 360) + 360) % 360;
		const normalizedSector =
			((sectorAngle % (Math.PI * 2)) + Math.PI * 2) % (Math.PI * 2);
		const sectorAngleDeg = (normalizedSector * 180) / Math.PI;
		const sectorRangeDeg = (sectorRange * 180) / Math.PI;

		// 计算扇形角度范围
		const startAngle = sectorAngleDeg - sectorRangeDeg / 2;
		const endAngle = sectorAngleDeg + sectorRangeDeg / 2;

		// 处理跨0度边界的情况
		if (startAngle < 0) {
			return normalizedPoint >= 360 + startAngle || normalizedPoint <= endAngle;
		} else if (endAngle > 360) {
			return normalizedPoint >= startAngle || normalizedPoint <= endAngle - 360;
		}
		return normalizedPoint >= startAngle && normalizedPoint <= endAngle;
	};

	// 绘制雷达背景
	const drawBackground = circles_num => {
		// 清除画布
		ctx.clearRect(0, 0, width, height);

		// 绘制外圆
		ctx.beginPath();
		ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
		ctx.strokeStyle = "rgba(0, 255, 0, 0.6)";
		ctx.lineWidth = 2;
		ctx.stroke();

		// 绘制同心圆
		for (let i = 1; i <= circles_num; i++) {
			const circleRadius = radius * (i / circles_num);
			ctx.beginPath();
			ctx.arc(centerX, centerY, circleRadius, 0, Math.PI * 2);
			ctx.strokeStyle = "rgba(0, 255, 0, 0.3)";
			ctx.lineWidth = 1;
			ctx.stroke();
		}

		// 绘制刻度线和方向文字
		for (let i = 0; i < 24; i++) {
			// 调整角度计算，使0度对应正上方
			const angle = (i * Math.PI) / 12 - Math.PI / 2;
			const textAngle = i * 15; // 0°到345°，每15°递增

			// 计算刻度线位置（调整Y轴方向使0度朝上）
			const x1 = centerX + Math.cos(angle) * (radius - 10);
			const y1 = centerY + Math.sin(angle) * (radius - 10);
			const x2 = centerX + Math.cos(angle) * radius;
			const y2 = centerY + Math.sin(angle) * radius;

			// 绘制刻度线
			ctx.beginPath();
			ctx.moveTo(x1, y1);
			ctx.lineTo(x2, y2);
			ctx.strokeStyle = "rgba(0, 255, 0, 0.5)";
			ctx.lineWidth = 1;
			ctx.stroke();

			// 绘制方向文字
			const directionText = getDirectionText(textAngle);
			const textRadius = radius - 30; // 文字距离圆心的距离
			const textX = centerX + Math.cos(angle) * textRadius;
			const textY = centerY + Math.sin(angle) * textRadius;

			ctx.fillStyle = "rgba(0, 255, 0, 0.8)";
			ctx.font = "12px Arial";
			ctx.textAlign = "center";
			ctx.textBaseline = "middle";
			ctx.fillText(directionText, textX, textY);
		}

		// 绘制十字线
		ctx.beginPath();
		ctx.moveTo(centerX, centerY - radius);
		ctx.lineTo(centerX, centerY + radius);
		ctx.moveTo(centerX - radius, centerY);
		ctx.lineTo(centerX + radius, centerY);
		ctx.strokeStyle = "rgba(0, 255, 0, 0.4)";
		ctx.lineWidth = 1;
		ctx.stroke();
	};

	// 计算两个经纬度之间的距离（公里）
	const getDistance = (lat1, lng1, lat2, lng2) => {
		const radLat1 = (lat1 * Math.PI) / 180;
		const radLat2 = (lat2 * Math.PI) / 180;
		const a = radLat1 - radLat2;
		const b = ((lng1 - lng2) * Math.PI) / 180;

		const s =
			2 *
			Math.asin(
				Math.sqrt(
					Math.pow(Math.sin(a / 2), 2) +
						Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)
				)
			);

		return s * EARTH_RADIUS;
	};

	// 计算方位角（从中心点到目标点的角度）
	const getBearing = (centerLat, centerLng, targetLat, targetLng) => {
		const dLng = ((targetLng - centerLng) * Math.PI) / 180;
		const lat1 = (centerLat * Math.PI) / 180;
		const lat2 = (targetLat * Math.PI) / 180;

		const y = Math.sin(dLng) * Math.cos(lat2);
		const x =
			Math.cos(lat1) * Math.sin(lat2) -
			Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLng);

		let bearing = (Math.atan2(y, x) * 180) / Math.PI;
		return (bearing + 360) % 360; // 转换为0-360度
	};

	const convertToCanvasCoord = (
		centerLat,
		centerLng,
		targetLat,
		targetLng,
		canvasSize,
		maxRadiusKm
	) => {
		const canvasRadius = canvasSize / 2;

		// 计算距离和方位角
		const distance = getDistance(centerLat, centerLng, targetLat, targetLng);
		const bearing = getBearing(centerLat, centerLng, targetLat, targetLng);

		// 将距离转换为canvas上的半径比例
		const scale = canvasRadius / maxRadiusKm;
		const canvasDistance = distance * scale;

		// 如果距离超过最大半径，返回null（不在圆形内）
		if (distance > maxRadiusKm) {
			return null;
		}

		// 计算canvas坐标（极坐标转直角坐标）
		const angle = ((bearing - 90) * Math.PI) / 180; // 调整角度（Canvas的0度在右侧）
		const x = canvasRadius + canvasDistance * Math.cos(angle);
		const y = canvasRadius + canvasDistance * Math.sin(angle);

		return { x, y, distance };
	};

	const drawPointsOnCanvas = (
		ctx,
		centerLat,
		centerLng,
		points,
		maxRadiusKm = 100
	) => {
		const canvasSize = width;

		points.forEach(point => {
			// 只绘制有脉冲激活状态的点
			if (!point.pulse.active && point.pulse.progress <= 0) return;

			const { lat, lng, color = "#00ff00", radius = 3 } = point;
			const coord = convertToCanvasCoord(
				centerLat,
				centerLng,
				lat,
				lng,
				canvasSize,
				maxRadiusKm
			);

			if (coord) {
				// 绘制中心点
				ctx.beginPath();
				ctx.arc(coord.x, coord.y, radius, 0, Math.PI * 2);
				ctx.fillStyle = color;
				ctx.fill();

				// 绘制脉冲效果
				if (point.pulse.progress > 0) {
					// 创建脉冲径向渐变
					const gradient = ctx.createRadialGradient(
						coord.x,
						coord.y,
						0,
						coord.x,
						coord.y,
						radius + point.pulse.progress * PULSE_MAX_RADIUS
					);

					// 设置渐变颜色停止点 (实现平滑渐变)
					gradient.addColorStop(
						0,
						`rgba(0, 0, 255, ${point.pulse.progress})`
					);
					gradient.addColorStop(
						0.5,
						`rgba(0, 0, 255, ${point.pulse.progress})`
					);
					gradient.addColorStop(1, `rgba(0, 0, 255, ${point.pulse.progress})`);

					// 绘制多层脉冲圈增强渐变效果
					for (let i = 1; i <= 3; i++) {
						const pulseSize =
							radius + point.pulse.progress * PULSE_MAX_RADIUS * (i / 3);
						const lineWidth = 3 - i * 0.8;

						ctx.beginPath();
						ctx.arc(coord.x, coord.y, pulseSize, 0, Math.PI * 2);
						ctx.strokeStyle = gradient;
						ctx.lineWidth = lineWidth;
						ctx.stroke();
					}

					// 更新脉冲进度 (降低速度)
					if (!point.pulse.active) {
						point.pulse.progress = Math.max(
							0,
							point.pulse.progress - PULSE_SPEED / 2
						);
					}
				}

				// 显示距离文本
				ctx.fillStyle = `rgba(255, 255, 255, ${
					point.pulse.progress * 0.8 + 0.2
				})`;
				ctx.font = "10px Arial";
				ctx.textAlign = "left";
				ctx.textBaseline = "middle";
				ctx.fillText(
					`${coord.distance.toFixed(1)}km`,
					coord.x + 5,
					coord.y + 5
				);
			}
		});
	};

	// 获取方向文字
	const getDirectionText = angle => {
		const directions = {
			0: "北", // N
			45: "东北", // NE
			90: "东", // E
			135: "东南", // SE
			180: "南", // S
			225: "西南", // SW
			270: "西", // W
			315: "西北", // NW
		};
		return directions[angle] || `${angle}°`; // 如果不是主要方向，显示角度
	};

	// 初始化扫描扇形渐变
	function initScanGradient() {
		// 创建从中心到边缘的径向渐变（扩大渐变范围）
		scanGradient = ctx.createRadialGradient(
			centerX,
			centerY,
			0,
			centerX,
			centerY,
			radius // 外半径扩大50%，使渐变延伸更远
		);
		// 调整颜色停止点，使渐变过渡更平缓
		scanGradient.addColorStop(0, "rgba(0, 255, 0, 0.3)");
		scanGradient.addColorStop(0.7, "rgba(0, 255, 0, 0.2)"); // 延迟透明度降低
		scanGradient.addColorStop(0.9, "rgba(0, 255, 0, 0.05)");
		scanGradient.addColorStop(1, "rgba(0, 255, 0, 0)");
	}

	// 绘制扫描扇形
	function drawScanSector() {
		ctx.save();
		ctx.beginPath();

		// 移动到圆心
		ctx.moveTo(centerX, centerY);

		// 计算扇形起始和结束角度（对准正北）
		const startAngle = scanSectorAngle - scanSectorRange / 2 - Math.PI / 2;
		const endAngle = scanSectorAngle + scanSectorRange / 2 - Math.PI / 2;

		// 绘制扇形
		ctx.arc(centerX, centerY, radius, startAngle, endAngle);

		ctx.closePath();
		ctx.fillStyle = scanGradient;
		ctx.fill();
		ctx.restore();
	}

	// 扫描动画循环
	function animateScan() {
		// 清除画布
		ctx.clearRect(0, 0, width, height);

		// 重新绘制所有元素
		drawBackground(4);
		drawScanSector(); // 绘制扫描扇形
		// 更新所有点的脉冲状态
		points.forEach(point => {
			const isInSector = isAngleInSector(
				point.bearing,
				scanSectorAngle,
				scanSectorRange
			);

			// 扇形扫到点时激活脉冲 (降低增速)
			if (isInSector) {
				point.pulse.active = true;
				point.pulse.progress = Math.min(
					1,
					point.pulse.progress + PULSE_SPEED / 2
				);
			} else {
				point.pulse.active = false;
			}
		});
		drawPointsOnCanvas(ctx, center.lat, center.lng, points, 100);

		// 更新扫描角度（循环扫描）
		scanSectorAngle += scanSpeed;
		if (scanSectorAngle >= Math.PI * 2) {
			scanSectorAngle = 0;
		}

		// 继续动画并更新ID
		animationId = requestAnimationFrame(animateScan);
	}

	const map_click = async () => {
		const response = await fetch(
			`https://cn.apihz.cn/api/ip/chaapi.php?id=10007651&key=1f5cc13ac7d8112399020f5404ff4faf`
		);
		const data = await response.json();
		console.log(data);
	};

	/**
	 * 根据中心点和半径计算外接矩形的西南角和东北角坐标
	 * @param {number} latCenter - 中心点纬度
	 * @param {number} lonCenter - 中心点经度
	 * @param {number} radiusMeters - 半径（米）
	 * @returns {Object} 包含西南角和东北角坐标的对象
	 */
	const calculateBoundingBox = (latCenter, lonCenter, radiusMeters) => {
		// 地球平均半径（米）
		const EARTH_RADIUS = 6371000;

		// 将角度转换为弧度
		const toRadians = degrees => degrees * (Math.PI / 180);
		// 将弧度转换为角度
		const toDegrees = radians => radians * (180 / Math.PI);

		// 计算纬度偏移量（度）
		const deltaLat = toDegrees(radiusMeters / EARTH_RADIUS);

		// 计算经度偏移量（度）
		const deltaLon = toDegrees(
			radiusMeters / (EARTH_RADIUS * Math.cos(toRadians(latCenter)))
		);

		// 计算边界坐标
		const minLat = latCenter - deltaLat;
		const maxLat = latCenter + deltaLat;
		const minLon = lonCenter - deltaLon;
		const maxLon = lonCenter + deltaLon;

		return {
			southWest: { lat: minLat, lng: minLon }, // 西南角
			northEast: { lat: maxLat, lng: maxLon }, // 东北角
			// 也提供其他格式的返回
			minLat: minLat,
			minLon: minLon,
			maxLat: maxLat,
			maxLon: maxLon,
		};
	};

	// 使用示例

	// const radius = 5000; // 5公里

	// const bbox = calculateBoundingBox(center.lat, center.lng, radius);

	// console.log("中心点:", center);
	// console.log("西南角:", bbox.southWest);
	// console.log("东北角:", bbox.northEast);
	// console.log("边界范围:", {
	// 	minLat: bbox.minLat,
	// 	minLon: bbox.minLon,
	// 	maxLat: bbox.maxLat,
	// 	maxLon: bbox.maxLon,
	// });
</script>

<style lang="less" scoped>
	.map_box {
		width: 100%;
		height: 100%;
		display: flex;
		justify-content: center;
		align-items: center;
		background-color: black;
		min-width: 1200px;
		min-height: 800px;

		.radar-container {
			width: 800px;
			height: 800px;
			border-radius: 50%;
			box-shadow: 0 0 40px rgba(0, 255, 0, 0.8);
			display: flex;
			justify-content: center;
			align-items: center;
			canvas {
				width: 800px;
				height: 800px;
				border-radius: 50%;
			}
		}
	}
</style>
